package com.qiqidream.admin.common.config;

import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.qiqidream.admin.common.factory.ResourceFactory;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.http.HttpMethod;
import org.springframework.security.web.util.matcher.AntPathRequestMatcher;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Set;

/**
 * 自定义配置
 * @author QiQiDream
 * @since 2019/11/21 10:55
 */
@Component
@PropertySource(value = "classpath:application-config.yml", factory = ResourceFactory.class)
@ConfigurationProperties(prefix = "custom.config")
@Data
public class IgnoresCustomConfig {
    /**
     * 需要忽略的 URL 格式，不考虑请求方法
     */
    private List<String> pattern = Lists.newArrayList();

    /**
     * 需要忽略的 GET 请求
     */
    private List<String> get = Lists.newArrayList();

    /**
     * 需要忽略的 POST 请求
     */
    private List<String> post = Lists.newArrayList();

    /**
     * 需要忽略的 DELETE 请求
     */
    private List<String> delete = Lists.newArrayList();

    /**
     * 需要忽略的 PUT 请求
     */
    private List<String> put = Lists.newArrayList();

    /**
     * 需要忽略的 HEAD 请求
     */
    private List<String> head = Lists.newArrayList();

    /**
     * 需要忽略的 PATCH 请求
     */
    private List<String> patch = Lists.newArrayList();

    /**
     * 需要忽略的 OPTIONS 请求
     */
    private List<String> options = Lists.newArrayList();

    /**
     * 需要忽略的 TRACE 请求
     */
    private List<String> trace = Lists.newArrayList();



    /**
     * 请求是否不需要进行权限拦截
     *
     * @param request 当前请求
     * @return true - 忽略，false - 不忽略
     */
    public boolean checkIgnores(HttpServletRequest request) {
        String method = request.getMethod();


        HttpMethod httpMethod = HttpMethod.resolve(method);
        if (ObjectUtils.isEmpty(httpMethod)) {
            httpMethod = HttpMethod.GET;
        }

        Set<String> ignores = Sets.newHashSet();

        switch (httpMethod) {
            case GET:
                ignores.addAll(getGet());
                break;
            case PUT:
                ignores.addAll(getPut());
                break;
            case HEAD:
                ignores.addAll(getHead());
                break;
            case POST:
                ignores.addAll(getPost());
                break;
            case PATCH:
                ignores.addAll(getPatch());
                break;
            case TRACE:
                ignores.addAll(getTrace());
                break;
            case DELETE:
                ignores.addAll(getDelete());
                break;
            case OPTIONS:
                ignores.addAll(getOptions());
                break;
            default:
                break;
        }

        ignores.addAll(getPattern());

        if (!ObjectUtils.isEmpty(ignores)) {
            for (String ignore : ignores) {
                AntPathRequestMatcher matcher = new AntPathRequestMatcher(ignore, method);
                if (matcher.matches(request)) {
                    return true;
                }
            }
        }
        return false;
    }
}
